package org.infodavid.common.model.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.infodavid.common.model.IEntity;
import org.infodavid.common.model.IGenericPropertiesMap;
import org.infodavid.common.model.IImageData;
import org.infodavid.common.model.ModelFactory;
import org.infodavid.common.model.components.IEMail;
import org.infodavid.common.model.components.ILocation;
import org.infodavid.common.model.components.IPhone;
import org.infodavid.common.model.components.IUri;

/**
 * The Class AbstractEntity.
 */
public abstract class AbstractEntity extends AbstractNamedCommented<Long> implements IEntity {

	/** serialVersionUID. */
	private static final long serialVersionUID = -1901279442917482570L;

	/** The emails. */
	private List<IEMail> emails;

	/** The identity. */
	private String identity;

	/** The image. */
	private IImageData image;

	/** The phones. */
	private List<IPhone> phones;

	/** The locations. */
	private List<ILocation> locations;

	/** The properties. */
	private IGenericPropertiesMap properties;

	/** The websites. */
	private List<IUri> websites;

	/**
	 * constructor.
	 * @param key the key
	 * @throws Exception the exception
	 */
	protected AbstractEntity(final Long key) throws Exception {
		super(key);
	}

	/**
	 * constructor.
	 * @throws Exception the exception
	 */
	protected AbstractEntity() throws Exception {
		super();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getLocations()
	 */
	public List<ILocation> getLocations() {
		return locations;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getEmails()
	 */
	public List<IEMail> getEmails() {
		return emails;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getIdentity()
	 */
	public String getIdentity() {
		return identity;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getImage()
	 */
	public IImageData getImage() {
		return image;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getPhones()
	 */
	public List<IPhone> getPhones() {
		return phones;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.data.IGenericObject#getProperties()
	 */
	public IGenericPropertiesMap getProperties() {
		return properties;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#getWebSites()
	 */
	public List<IUri> getWebSites() {
		return websites;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IBasicDataObject#init()
	 */
	@Override
	public void init() throws Exception {
		super.init();

		properties = ModelFactory.getInstance().create(IGenericPropertiesMap.class);
		emails = new ArrayList<IEMail>();
		locations = new ArrayList<ILocation>();
		identity = null;
		image = null;
		phones = new ArrayList<IPhone>();
		websites = new ArrayList<IUri>();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.entities.IEntity#setIdentity(java.lang.String)
	 */
	public void setIdentity(final String value) {
		if (!equals(identity, value)) {
			final Object old = identity;
			identity = value;
			markModified(IDENTITY, old, identity);
		}
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.model.IEntity#setImage(org.infodavid.common.model.IImageData)
	 */
	public void setImage(final IImageData value) {
		if (!equals(image, value)) {
			final Object old = image;
			image = value;
			markModified(IMAGE, old, image);
		}
	}

	/**
	 * Sets the properties.
	 * @param values the properties
	 */
	public void setProperties(final IGenericPropertiesMap values) {
		final Object old = properties;
		properties = values;
		markModified(PROPERTIES, old, properties);
	}

	/**
	 * Sets the emails.
	 * @param value the emails
	 */
	public void setEmails(final List<IEMail> value) {
		emails = value;
	}

	/**
	 * Sets the phones.
	 * @param value the phones
	 */
	public void setPhones(final List<IPhone> value) {
		phones = value;
	}

	/**
	 * Sets the web sites.
	 * @param value the web sites
	 */
	public void setWebSites(final List<IUri> value) {
		websites = value;
	}

	/**
	 * Sets the locations.
	 * @param value the locations
	 */
	public void setLocations(final List<ILocation> value) {
		locations = value;
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.impl.model.DataObjectImpl#toString(java.lang.StringBuffer)
	 */
	@Override
	protected StringBuffer toString(final StringBuffer builder) {
		super.toString(builder);

		builder.append(" [emails=");

		if (emails == null) {
			builder.append("null");
		}
		else {
			final Iterator<IEMail> ite = emails.iterator();

			if (ite.hasNext()) {
				builder.append(ite.next().getValue());

				while (ite.hasNext()) {
					builder.append(',');
					builder.append(ite.next().getValue());
				}
			}
		}

		builder.append(", identity=");
		builder.append(identity);
		builder.append(", image=");
		builder.append(image);
		builder.append(", locations=");

		if (locations == null) {
			builder.append("null");
		}
		else {
			final Iterator<ILocation> ite = locations.iterator();

			if (ite.hasNext()) {
				builder.append(ite.next().getName());

				while (ite.hasNext()) {
					builder.append(',');
					builder.append(ite.next().getName());
				}
			}
		}

		builder.append(", phones=");

		if (phones == null) {
			builder.append("null");
		}
		else {
			final Iterator<IPhone> ite = phones.iterator();

			if (ite.hasNext()) {
				builder.append(ite.next().getValue());

				while (ite.hasNext()) {
					builder.append(',');
					builder.append(ite.next().getValue());
				}
			}
		}

		builder.append(", properties=");
		builder.append(properties);
		builder.append(", websites=");

		if (websites == null) {
			builder.append("null");
		}
		else {
			final Iterator<IUri> ite = websites.iterator();

			if (ite.hasNext()) {
				builder.append(ite.next().getValue());

				while (ite.hasNext()) {
					builder.append(',');
					builder.append(ite.next().getValue());
				}
			}
		}

		builder.append("]");

		return builder;
	}
}
